extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};


// 派生宏（Derive Macros）
#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
    // 解析输入为 DeriveInput
    let ast = parse_macro_input!(input as DeriveInput);

    // 获取结构体的名称
    let name = &ast.ident;

    // 生成代码
    let expanded = quote! {
        impl #name {
            fn hello(&self) {
                println!("Hello, I am {}", stringify!(#name));
            }
        }
    };

    // 返回生成的代码
    TokenStream::from(expanded)
}

// 属性宏（Attribute Macros）
#[proc_macro_attribute]
pub fn log_function(_attr: TokenStream, item: TokenStream) -> TokenStream {
    // 解析输入为函数
    let input = parse_macro_input!(item as syn::ItemFn);

    // 获取函数名称
    let fn_name = &input.sig.ident;

    let block = &input.block;

    // 生成代码
    let expanded = quote! {
        fn #fn_name() {
            println!("Log: Calling function {}", stringify!(#fn_name));
            #block
        }
    };

    TokenStream::from(expanded)
}

#[proc_macro_attribute]
pub fn my_struct(_attr: TokenStream, item: TokenStream) -> TokenStream {
    // 解析输入为函数
    let input = parse_macro_input!(item as syn::ItemStruct);

    // 获取函数名称
    let fn_name = &input.ident;

    let fields = &input.fields;

    // 生成代码
    let expanded = quote! {
        #[derive(Debug)]
        #[allow(unused)]
        struct #fn_name #fields
    };

    TokenStream::from(expanded)
}

// 函数宏（Function-like Macros）
#[proc_macro]
pub fn my_println(input: TokenStream) -> TokenStream {
    // 解析输入为表达式
    let input = parse_macro_input!(input as syn::Expr);

    // 生成代码
    let expanded = quote! {
        println!("{}", #input);
    };

    TokenStream::from(expanded)
}